<?php
/**
 * Created by PhpStorm.
 * Author: 芸签cms www.yunqiancms.com
 * User: sun
 * Date: 2022/7/7
 * Time: 10:27 AM
 */
namespace app\common\services\plugin;

use app\common\exceptions\BizException;
use app\common\helpers\Cache;
use Illuminate\Support\Facades\DB;
use app\common\models\Plugin as PluginModel;
use app\common\services\plugin\Plugin;
use Illuminate\Support\Collection;
use Illuminate\Filesystem\Filesystem;
use Illuminate\Contracts\Foundation\Application;
use Illuminate\Contracts\Events\Dispatcher;
use app\common\events\plugin\PluginWasEnabled;
use app\common\events\plugin\PluginWasDisabled;
use app\common\events\plugin\PluginWasDeleted;

class PluginService
{
    const CACHE_KEY_PLUGINS_LIST = 'app:common:services:PluginService:getPlugins:plugins_list';

    const CACHE_KEY_PACKAGE_PRE = 'app:common:services:PluginService:plugin_package:';

    protected $app;

    /**
     * @var OptionRepository
     */

    /**
     * @var Dispatcher
     */
    protected $dispatcher;

    protected $pluginsNameMap;

    /**
     * @var Filesystem
     */
    protected $filesystem;


    protected $plugins;

    public function __construct(
        Application $app,
        Dispatcher $dispatcher,
        Filesystem $filesystem
    )
    {
        $this->app = $app;
        $this->dispatcher = $dispatcher;
        $this->filesystem = $filesystem;
        if (file_exists(base_path().'/bootstrap/install.lock')) {
            $this->pluginsNameMap = PluginModel::getAllEnabledNameMap();
        }else{
            $this->pluginsNameMap = [];
        }

    }

    /**
     * 获取本地的插件列表
     * @return Collection|mixed
     */
    public function getPlugins(){
        if (is_null($this->plugins)) {
            $this->plugins = Cache::get(self::CACHE_KEY_PLUGINS_LIST);
            if (!is_null($this->plugins)) {
                return $this->plugins;
            }
            $plugins = new Collection();
            $pluginDirs = $this->filesystem->directories(base_path('plugins'));

            foreach ($pluginDirs as $pluginDir) {
                if (file_exists($pluginDir . "/package.json")) {
                    $plugin = new Plugin($pluginDir);
                    $plugin->setInstalled(true);
                    $plugin->setEnabled($this->isEnabled($plugin->name));

                    $plugins->put($plugin->name, $plugin);

                }
            }

            $this->plugins = $plugins->sortBy(function ($plugin) {
                return $plugin->name;
            });
            Cache::put(self::CACHE_KEY_PLUGINS_LIST,$this->plugins,5);
        }
        return $this->plugins;
    }

    /**
     * @param $name
     * @return \app\common\services\plugin\Plugin
     */
    public function getPlugin($name)
    {
        return $this->getPlugins()->get($name);
    }
    public function getEnablePlugin($name)
    {
        return $this->getEnabledPlugins()->get($name);
    }
    public function enable($name)
    {
        $model = pluginModel::getByName($name);
        if(!$model['id']){
            $model = new pluginModel();
            $model->site_id = \YunCms::siteId();
        }
        $model->name =$name;
        $model->status = pluginModel::STATUS_NORMAL;
        $model->save();
        $plugin = $this->getPlugin($name);
        //$enabled = $this->getEnabled();
        //$plugin->setEnabled($name);
        $plugin->app()->init();
        $this->dispatcher->dispatch(new PluginWasEnabled($plugin));
    }
    public function disable($name)
    {
        $model = pluginModel::getByName($name);
        $model->status = pluginModel::STATUS_BAN;
        $model->save();
        ///$enabled = $this->getEnabled();

        $plugin = $this->getPlugin($name);

        //$this->option->editDisable($enabled[$name]['id']);

        $this->dispatcher->dispatch(new PluginWasDisabled($plugin));
    }
    public function uninstall($name){
        $plugin = $this->getPlugin($name);

        $this->disable($name);

        // fire event before deleeting plugin files
        // $this->dispatcher->fire(new events\PluginWasDeleted($plugin));

        $find = storage_path('/logs/plugin_uninstall.log');

        if(!file_exists($find)){
            fopen($find,'a');
        }

        file_put_contents($find, date('Y-m-d H:i:s').'操作员：'. \Auth::guard('admin')->user()->uid.'卸载了插件'.$name.PHP_EOL, FILE_APPEND);

        $this->filesystem->deleteDirectory($plugin->getPath());

        // refresh plugin list
        $this->plugins = null;
    }
    public function isEnabled($name){
        $res = false;
        if($this->pluginsNameMap[$name]['status'] == PluginModel::STATUS_NORMAL){
            $res = true;
        }
        return $res;
    }
    public function getEnabledPlugins()
    {
        $only = [];
        $enabledMap = $this->getEnabled();
        foreach ($enabledMap as $key => $plugin) {
            if ($plugin['status']==PluginModel::STATUS_NORMAL) {
                $only[] = $key;
            }
        }
        return $this->getPlugins()->only($only);
    }
    public function getEnabled()
    {
        return $this->pluginsNameMap;
    }
    public function app(){
        $pluginApplicationClass = $this->namespace . '\\' . 'PluginApplication';

        if (class_exists($pluginApplicationClass)) {

            $this->pluginApp = new $pluginApplicationClass($this);
        } else {

            $this->pluginApp = new PluginApplication($this);
        }
    }
}